package com.jintian.smart.kernel.common.expr.format.reader;

import com.jintian.smart.kernel.common.expr.format.ExpressionReader;
import com.jintian.smart.kernel.common.expr.format.FormatException;

import java.io.IOException;

/**
 * 词元读取器工厂
 */
public class ElementReaderFactory {

    /**
     * 根据流开头构造不同的词元读取 流应该非空格开头
     *
     * @param reader
     * @return ElementReader
     * @throws IOException
     * @throws FormatException
     */
    public static ElementReader createElementReader(ExpressionReader reader) throws IOException, FormatException {
        // 读一个char
        reader.mark(0);
        int b = reader.read();
        reader.reset();
        if (b != -1) {
            char c = (char) b;
            try {
                if (StringTypeReader.START_MARK.indexOf(c) >= 0 /*
                 * c == StringTypeReader .START_MARK
                 */) {// "开头，构造字符串读取器
                    return StringTypeReader.class.newInstance();
                } else if (c == DateTypeReader.START_MARK) {// [开头，构造日期读取器
                    return DateTypeReader.class.newInstance();
                } else if (c == FunctionTypeReader.START_MARK || c == FunctionTypeReader.LIST_START) {// $开头，构造函数读取器
                    return FunctionTypeReader.class.newInstance();
                } else if (SplitorTypeReader.SPLITOR_CHAR.indexOf(c) >= 0 || c == FunctionTypeReader.LIST_END) {// 如果是分隔符，构造分隔符读取器
                    return SplitorTypeReader.class.newInstance();
                } else if (NumberTypeReader.NUMBER_CHARS.indexOf(c) >= 0) {// 以数字开头，构造数字类型读取器
                    return NumberTypeReader.class.newInstance();
                } else if (OperatorTypeReader.isOperatorStart(reader)) {// 如果前缀是运算符，构造运算符读取器
                    return OperatorTypeReader.class.newInstance();
                } else {
                    if (tryIsFunction(reader))
                        return FunctionTypeReader.class.newInstance();
                    return VariableTypeReader.class.newInstance();// 否则构造一个变量读取器
                }
            } catch (Exception e) {
                throw new FormatException(e);
            }

        } else {
            throw new FormatException("流已结束");
        }
    }

    /**
     * 从流中读取函数类型的ExpressionToken
     *
     * @param sr
     * @return
     * @throws FormatException
     * @throws IOException
     */
    private static boolean tryIsFunction(ExpressionReader sr) throws FormatException, IOException {
        sr.mark(sr.getCruuentIndex());
        try {
            StringBuffer sb = new StringBuffer();
            boolean readStart = true;
            int b = -1;
            while ((b = sr.read()) != -1) {
                char c = (char) b;
                if (ElementReader.IGNORE_CHAR.indexOf(c) >= 0) {
                    continue;
                }
                if ('(' == c && !readStart) {// 单词停止符,并且忽略第一个字符
                    sr.reset();
                    return true;
                }
                if (!Character.isJavaIdentifierPart(c) && FunctionTypeReader.NM_SPLIT != c) {
                    return false;
                }
                if (readStart) {
                    if (!Character.isJavaIdentifierStart(c)) {
                        return false;
                    }
                    readStart = false;
                }
                sb.append(c);

            }
        } finally {
            sr.reset();
        }
        return false;
    }

}
